From c3049f0f7c2653251da65b50f823510150341581 Mon Sep 17 00:00:00 2001 From: Keir Fraser Date: Fri, 25 Jun 2010 15:44:58 +0100 Subject: [PATCH] x86 paging_domctl: reinstates the breaks in the flow control (and folds two identical cases together) and fixes the memory leak that was causing a crash. Signed-off-by: Tim Deegan --- xen/arch/x86/mm/paging.c | 14 ++++++-------- xen/arch/x86/mm/shadow/common.c | 25 +++++++++++++++++-------- 2 files changed, 23 insertions(+), 16 deletions(-) diff --git a/xen/arch/x86/mm/paging.c b/xen/arch/x86/mm/paging.c index b5ef2c6eb0..66548ef600 100644 --- a/xen/arch/x86/mm/paging.c +++ b/xen/arch/x86/mm/paging.c @@ -700,23 +700,21 @@ int paging_domctl(struct domain *d, xen_domctl_shadow_op_t *sc, */ switch ( sc->op ) { + + case XEN_DOMCTL_SHADOW_OP_ENABLE: + if ( !(sc->mode & XEN_DOMCTL_SHADOW_ENABLE_LOG_DIRTY) ) + break; + /* Else fall through... */ case XEN_DOMCTL_SHADOW_OP_ENABLE_LOGDIRTY: if ( hap_enabled(d) ) hap_logdirty_init(d); return paging_log_dirty_enable(d); - case XEN_DOMCTL_SHADOW_OP_ENABLE: - if ( sc->mode & XEN_DOMCTL_SHADOW_ENABLE_LOG_DIRTY ) - { - if ( hap_enabled(d) ) - hap_logdirty_init(d); - return paging_log_dirty_enable(d); - } - case XEN_DOMCTL_SHADOW_OP_OFF: if ( paging_mode_log_dirty(d) ) if ( (rc = paging_log_dirty_disable(d)) != 0 ) return rc; + break; case XEN_DOMCTL_SHADOW_OP_CLEAN: case XEN_DOMCTL_SHADOW_OP_PEEK: diff --git a/xen/arch/x86/mm/shadow/common.c b/xen/arch/x86/mm/shadow/common.c index 1c85cb23d1..a42de64725 100644 --- a/xen/arch/x86/mm/shadow/common.c +++ b/xen/arch/x86/mm/shadow/common.c @@ -3241,9 +3241,12 @@ void shadow_teardown(struct domain *d) { int i; mfn_t *oos_snapshot = v->arch.paging.shadow.oos_snapshot; - for(i = 0; i < SHADOW_OOS_PAGES; i++) + for ( i = 0; i < SHADOW_OOS_PAGES; i++ ) if ( mfn_valid(oos_snapshot[i]) ) + { shadow_free(d, oos_snapshot[i]); + oos_snapshot[i] = _mfn(INVALID_MFN); + } } #endif /* OOS */ } @@ -3395,17 +3398,23 @@ static int shadow_one_bit_disable(struct domain *d, u32 mode) #endif make_cr3(v, pagetable_get_pfn(v->arch.guest_table)); +#if (SHADOW_OPTIMIZATIONS & SHOPT_OUT_OF_SYNC) + { + int i; + mfn_t *oos_snapshot = v->arch.paging.shadow.oos_snapshot; + for ( i = 0; i < SHADOW_OOS_PAGES; i++ ) + if ( mfn_valid(oos_snapshot[i]) ) + { + shadow_free(d, oos_snapshot[i]); + oos_snapshot[i] = _mfn(INVALID_MFN); + } + } +#endif /* OOS */ } /* Pull down the memory allocation */ if ( sh_set_allocation(d, 0, NULL) != 0 ) - { - // XXX - How can this occur? - // Seems like a bug to return an error now that we've - // disabled the relevant shadow mode. - // - return -ENOMEM; - } + BUG(); /* In fact, we will have BUG()ed already */ shadow_hash_teardown(d); SHADOW_PRINTK("un-shadowing of domain %u done." " Shadow pages total = %u, free = %u, p2m=%u\n", -- 2.30.2